package com.sgai.zero_robot.utils.record;

import static com.sgai.zero_robot.utils.LogUtil.rootPath;

import android.app.Notification;
import android.app.Service;
import android.content.ContentValues;
import android.content.Intent;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.MediaRecorder;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.provider.MediaStore;
import android.util.DisplayMetrics;
import android.view.WindowManager;

import androidx.annotation.Nullable;

import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class ScreenRecordService extends Service {
    public static final String EXTRA_RESULT_CODE = "resultCode";
    public static final String EXTRA_DATA_INTENT = "dataIntent"; // projection permission data
    public static final String EXTRA_CONFIG = "config";

    private MediaProjection mediaProjection;
    private VirtualDisplay virtualDisplay;
    private MediaRecorder mediaRecorder;
    private RecorderConfig config;

    private Uri currentOutputUri;

    private final IBinder binder = new LocalBinder();
    public class LocalBinder extends Binder {
        public ScreenRecordService getService() { return ScreenRecordService.this; }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) { return binder; }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        NotificationHelper.ensureChannel(this);
        Notification n = NotificationHelper.buildRecordingNotification(this, "准备开始...");
        startForeground(1, n);

        int resultCode = intent.getIntExtra(EXTRA_RESULT_CODE, -1);
        Intent data = intent.getParcelableExtra(EXTRA_DATA_INTENT);
        config = (RecorderConfig) intent.getSerializableExtra(EXTRA_CONFIG);
        if (config == null) config = new RecorderConfig();

        MediaProjectionManager mpm = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
        mediaProjection = mpm.getMediaProjection(resultCode, data);
        if (mediaProjection == null) {
            stopSelf();
            return START_NOT_STICKY;
        }

        try {
            setupAndStartRecorder();
        } catch (Exception e) {
            e.printStackTrace();
            stopSelf();
        }
        return START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        stopRecordingInternal();
    }

    public void stopRecording() {
        stopRecordingInternal();
        stopForeground(true);
        stopSelf();
    }
    private void stopRecordingInternal() {
        try {
            if (virtualDisplay != null) {
                virtualDisplay.release();
                virtualDisplay = null;
            }
            if (mediaRecorder != null) {
                try { mediaRecorder.stop(); } catch (Exception ignored) {}
                mediaRecorder.reset();
                mediaRecorder.release();
                mediaRecorder = null;
            }
            if (mediaProjection != null) {
                mediaProjection.stop();
                mediaProjection = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private void setupAndStartRecorder() throws IOException {
// 1) 计算分辨率 & dpi
        WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
        DisplayMetrics metrics = new DisplayMetrics();
        wm.getDefaultDisplay().getRealMetrics(metrics);
        int width = metrics.widthPixels;
        int height = metrics.heightPixels;
        int density = metrics.densityDpi;

// 2) 创建输出目标: 写入 MediaStore（无需存储权限）
        String displayName = config.fileDisplayName;
        if (displayName == null || displayName.trim().isEmpty()) {
            displayName = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
        }
        String mimeType = "video/mp4";
        Uri collection;
        ContentValues values = new ContentValues();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            collection = MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
            values.put(MediaStore.Video.Media.DISPLAY_NAME, displayName + ".mp4");
            values.put(MediaStore.Video.Media.MIME_TYPE, mimeType);
            values.put(MediaStore.Video.Media.RELATIVE_PATH, "Movies/ScreenRecords");
        } else {
            collection = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
            values.put(MediaStore.Video.Media.DISPLAY_NAME, displayName);
            values.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");

            // 手动指定绝对路径
            File moviesDir = new File(rootPath + "ScreenRecords/");
            File outFile = new File(moviesDir, displayName+".mp4");
            // 确保父目录存在
            if (!outFile.getParentFile().exists()) {
                outFile.getParentFile().mkdirs();
            }

            values.put(MediaStore.Video.Media.DATA, outFile.getAbsolutePath());
        }

        currentOutputUri = getContentResolver().insert(collection, values);
        if (currentOutputUri == null) throw new IOException("无法创建输出文件");
        FileDescriptor fd = getContentResolver().openFileDescriptor(currentOutputUri, "w").getFileDescriptor();

// 3) 配置 MediaRecorder
        mediaRecorder = new MediaRecorder();

        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        mediaRecorder.setVideoEncodingBitRate(config.videoBitrate);
        mediaRecorder.setVideoFrameRate(config.videoFrameRate);
        mediaRecorder.setVideoSize(width, height);
        mediaRecorder.setOutputFile(fd);
        mediaRecorder.prepare();

// 4) 创建 VirtualDisplay，将 MediaRecorder 的 Surface 作为输入
        virtualDisplay = mediaProjection.createVirtualDisplay(
                "ScreenRecord",
                width,
                height,
                density,
                DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                mediaRecorder.getSurface(),
                null,
                null
        );

        mediaRecorder.start();

// 更新通知
        Notification n = NotificationHelper.buildRecordingNotification(this, "点击返回应用可停止录制");
        startForeground(1, n);
    }


}
